/* eslint-disable no-use-before-define */
// 连接存储空间
const playerStorage = storage.getDataStorage('player');
// 排行榜存储100人的数据
const RankCount = 100;
// 排行榜数据
export let rankData: GameRankUserData[] = [];

initRank();

world.onPlayerJoin(async ({ }) => {
    // 加载玩家数据
    // await loadPlayer(entity);
    // console.log(
    //     entity.player.name +
    //         ' 合并数据库后的数据： ' +
    //         JSON.stringify(entity.data)
    // );

    // 右键显示排行榜
    // entity.player.onPress(({ button }) => {
    //     if (button == GameButtonType.ACTION1) {
    //         entity.player.dialog({
    //             type: GameDialogType.SELECT,
    //             content: rankData.map((e: GameRankUserData, i: number) => { return `第${i + 1}名 ${e.name} 得分: ${e.time}` }).join('\n'),
    //             title: '排行榜',
    //             options: ['好的'],
    //         })
    //     }
    // })
});

// 初始化排行榜数据
async function initRank() {
    while (true) {
        try {
            const data = await playerStorage.get('rank');
            if (data && data.value) {
                console.log(
                    '数据库中的排行榜数据： ' + JSON.stringify(data.value)
                );
                rankData = data.value as unknown as GameRankUserData[];
            } else {
                console.log('数据库中暂无排行榜数据');
            }
            // 获取数据成功，则退出循环
            return;
        } catch (e) {
            console.log(e);
        }
        // 假如获取数据失败，则一秒后重试
        await sleep(1000);
    }
}

// 更新排行榜数据
export async function updateRankData(user: GamePlayerEntity) {
    if (user.isGuest()) {
        return;
    }
    // 假如排行榜上榜人数还没达到预期人数
    if (rankData.length < RankCount) {
        const index = rankData.findIndex(
            (e) => e.userId === user.player.userId
        );
        // 如果此玩家已上榜，则先删除ta的数据
        if (index >= 0) {
            rankData.splice(index, 1);
        }
        rankData.push({
            userId: user.player.userId,
            name: user.player.name,
            time: user.data.time,
        });
    } else {
        const lastOne = rankData[rankData.length - 1];
        // 假如排行榜中最后一名的时间 长于该玩家，则替换ta
        if (lastOne.time < user.data.time) {
            rankData.pop();
            const index = rankData.findIndex(
                (e) => e.userId === user.player.userId
            );
            if (index >= 0) {
                rankData.splice(index, 1);
            }
            rankData.push({
                userId: user.player.userId,
                name: user.player.name,
                time: user.data.time,
            });
        }
    }
    // 按时间按升序排序
    rankData.sort((a, b) => a.time - b.time);
    // 推送到数据库
    playerStorage.update('rank', () => rankData as never);
}

// 保存数据到数据库
export async function savePlayer(entity: GamePlayerEntity) {
    const { userId } = entity.player;
    while (true) {
        try {
            // 存储数据成功，则退出循环
            return await playerStorage.update(userId, () => entity.data);
        } catch (e) {
            console.log(e);
        }
        // 假如存储数据失败，则一秒后重试
        await sleep(1000);
    }
}

// 从数据库拉数据，并与默认数据合并
export async function loadPlayer(entity: GamePlayerEntity) {
    // 先给玩家初始化默认数据
    initPlayer(entity);

    // 游客无法加载数据
    if (entity.isGuest()) {
        entity.player.directMessage('你还没有登录，不会存储你的游戏数据哦');
        return;
    }

    const { userId } = entity.player;
    while (true) {
        try {
            const data = await playerStorage.get(userId);
            if (data && data.value) {
                console.log(
                    entity.player.name +
                        ' 数据库中的数据： ' +
                        JSON.stringify(data.value)
                );
                assignData(entity.data, data.value);
                /**
                 * 假如此处用 Object.assign(entity.data, data.value)
                 * 会导致在initPlayer函数里给entity.data.info 新增字段 param3时，
                 * param3字段并不会被并入entity.data.info内
                 */
            } else {
                console.log(entity.player.name + ' 数据库中暂无数据');
            }
            // 获取数据成功，则退出循环
            return;
        } catch (e) {
            console.log(e);
        }
        // 假如获取数据失败，则一秒后重试
        await sleep(1000);
    }
}

// 初始化玩家默认数据
export function initPlayer(entity: GamePlayerEntity) {
    entity.data = {
        name: entity.player.name, // 玩家姓名
        userId: entity.player.userId, // 玩家userId
        time: 0, // 时间
    };
}

// 将object更深层的赋值，而不是简单的覆盖，可以避免玩家data内新增的字段被吞掉的情况
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function assignData(defaultData: any, dbData: any) {
    if (!dbData) {
        return;
    }
    const dbDataKeys = Object.keys(dbData);
    for (const k of dbDataKeys) {
        if (typeof defaultData[k] === 'object') {
            assignData(defaultData[k], dbData[k]);
        } else {
            defaultData[k] = dbData[k];
        }
    }
}

// 该玩家是游客
GameEntity.prototype.isGuest = function () {
    if (this.player) {
        return this.player.userId === '0' || this.player.userId === '';
    }
    return false;
};
